package com.pubinfo.passbook.data.quartz.service.impl;

import com.pubinfo.passbook.common.config.ProfileConfig;
import com.pubinfo.passbook.common.entity.TPassbook;
import com.pubinfo.passbook.common.mapper.TMdmSupplierBankMapper;
import com.pubinfo.passbook.common.mapper.TMdmSupplierMapper;
import com.pubinfo.passbook.common.mapper.TSourceInvoiceMapper;
import com.pubinfo.passbook.common.mapper.TSourcePassbookMapper;
import com.pubinfo.passbook.common.model.bo.passbook.TPassbookDist;
import com.pubinfo.passbook.common.model.constant.StaffStatusEnum;
import com.pubinfo.passbook.common.model.dto.witeoff.MedicineOnJobOrRetireDTO;
import com.pubinfo.passbook.common.model.dubbo.ESBServiceData;
import com.pubinfo.passbook.common.model.ruler.UserAcc;
import com.pubinfo.passbook.common.model.vo.base.JsonResult;
import com.pubinfo.passbook.common.service.dubbo.DubboService;
import com.pubinfo.passbook.common.service.master.TInvoiceService;
import com.pubinfo.passbook.common.service.master.TRuleGenusService;
import com.pubinfo.passbook.common.service.mss.HttpService;
import com.pubinfo.passbook.common.service.ruler.CheckService;
import com.pubinfo.passbook.common.utils.task.ConstantUtil;
import com.pubinfo.passbook.data.quartz.service.MedicineOnJobOrRetireAutoReimbursement;
import com.pubinfo.passbook.data.service.DownLoadPDFService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class MedicineOnJobOrRetireAutoReimbursementImpl implements MedicineOnJobOrRetireAutoReimbursement {
  @Autowired
  DownLoadPDFService downLoadPDFService;
  @Autowired
  TMdmSupplierBankMapper bankMapper;
  @Value("${protest.budgetSet}")
  String budgetSet;
  @Autowired
  TMdmSupplierMapper supplierMapper;
  @Autowired
  TSourcePassbookMapper invoiceMapper;
  @Autowired
  TRuleGenusService genusService;
  @Autowired
  CheckService checkService;
  @Autowired
  TSourceInvoiceMapper sourceInvoiceMapper;
  @Autowired
  TInvoiceService invoiceService;
  @Autowired
  HttpService httpService;
  @Resource
  ProfileConfig config;
  @Autowired
  DubboService vatService;
  
  
  @SneakyThrows
  @Override
  public JsonResult<String> autoReimbursement(List<String> eInvoiceId) {
    //查询没有报账的医药费票据
    //TODO 查询出多个没有报账的发票,后续需要过滤出已经报账的发票
    List<TPassbookDist> tPassbookList = invoiceMapper.findAutoReimbursement(eInvoiceId);
    //过滤省公司
    List<String> nsrsbhs = ConstantUtil.getShengGongSiNsrsbh();
    List<TPassbookDist> distList = tPassbookList.stream().filter(tPassbook -> !nsrsbhs.contains(tPassbook.getNsrsbh())).collect(Collectors.toList());
    //对同一识别号的发票进行分组
    reimbursement(distList);
    return null;
  }
  private void reimbursement(List<TPassbookDist> tPassbookList) {
    if (!CollectionUtils.isEmpty(tPassbookList)) {
      //按所属公司分组
      String batchId = UUID.randomUUID().toString();
      Map<String, List<TPassbookDist>> cityMap = tPassbookList.stream().collect(Collectors.groupingBy(TPassbookDist::getDistrictId));
      for (Map.Entry<String, List<TPassbookDist>> mapItem : cityMap.entrySet()) {
        // 如果当前未到报销时间,则不进行报账.
        Map<String, List<TPassbook>> groupNsrsbhMap = mapItem.getValue().stream().collect(Collectors.groupingBy(TPassbook::getNsrsbh));
        for (Map.Entry<String, List<TPassbook>> entry : groupNsrsbhMap.entrySet()) {
          List<TPassbook> tPassbookItem = entry.getValue();
          TPassbook passbook = tPassbookItem.get(0);
          String sapCompayCode = sourceInvoiceMapper.selectCompanyType(passbook.getNsrsbh());
          //其他类型的不进报账
          if (!"0".equals(sapCompayCode)) {
            //再按票据所有人身份证号分组
            Map<String, List<TPassbook>> groupUserMap = tPassbookItem.stream().collect(Collectors.groupingBy(TPassbook::getPayerPartyCode));
            for (Map.Entry<String, List<TPassbook>> userEntry : groupUserMap.entrySet()) {
              List<TPassbook> tPassbookUserItem = userEntry.getValue();
              downLoadPDFService.downLoadPDFByPassbook(tPassbookUserItem);
              if (!CollectionUtils.isEmpty(tPassbookUserItem)) {
                sendTo(sapCompayCode, tPassbookUserItem, batchId);
              }
  
            }
  
          }
          
        }
      }
      
    }
  }
  
  @Override
  public void autoJobReimbursement(List<TPassbook> tPassbooks) {
    //判断是否为省公司,如果是省公司,则不直接发起报账
    List<String> nsrsbhs = ConstantUtil.getShengGongSiNsrsbh();
    List<String> eInvoiceIds = tPassbooks.stream().filter(tPassbook -> !nsrsbhs.contains(tPassbook.getNsrsbh())).map(TPassbook::getEInvoiceId).collect(Collectors.toList());
    if (!CollectionUtils.isEmpty(eInvoiceIds)) {
      List<TPassbookDist> tPassbookList = invoiceMapper.findAutoReimbursement(eInvoiceIds);
      reimbursement(tPassbookList);
    }
  
  }
  
  private void sendTo(String sapCompayCode, List<TPassbook> tPassbookUserItem, String batchId) {
    TPassbook tPassbookUser = tPassbookUserItem.get(0);
    String idNo = tPassbookUser.getPayerPartyCode();
    Boolean isGenus = genusService.isGenus(idNo);
    //如果不是供属,则报账人即是票据付款人,如果是供属,则需查询供属表,关联出人员账号.
    String staffCode = getStaffCode(idNo, isGenus);
    //如果员工状态不是在职,并且当前为供属报账,则不处理.
    ESBServiceData.CertDetail certDetail = vatService.getPersonsDetailByIdNo(staffCode);
    if ((isGenus && !"在职".equals(certDetail.getStaffStatus())) || certDetail == null) {
      return;
    }
    Integer status = StaffStatusEnum.getEnumByStatus(certDetail.getStaffStatus()).getCode();
    UserAcc userAcc = checkService.getUserAcc(staffCode, false);
    if (userAcc != null) {
      //生产环境走默认配置，protest 走文件配置
      MedicineOnJobOrRetireDTO dto = new MedicineOnJobOrRetireDTO(config.getActiveProfile(), status, sapCompayCode, null, userAcc, isGenus, null, budgetSet, BigDecimal.ZERO);
      List<String> invoiceIds = tPassbookUserItem.stream().map(TPassbook::getEInvoiceId).collect(Collectors.toList());
      dto.setInvoiceIds(invoiceIds);
      dto.getManage().setBatchId(batchId);
      httpService.autoMedicineOnJobAutoCreateWriteoff(dto, false);
    }
    
  }
  
  private String getStaffCode(String idNo, Boolean isGenus) {
    String staffCode; //查询票据所有人的人员账号,如果是供属,则查询员工账号
    if (isGenus) {
      staffCode = genusService.findAcctByidNo(idNo);
    } else {
      staffCode = vatService.getPersonsDetailByAcct(idNo);
    }
    return staffCode;
  }
}
